package com.haoqizhe.kernel.mybatis.generator.plugins;

import com.haoqizhe.kernel.mybatis.generator.utils.AnnotationEnum;
import com.haoqizhe.kernel.mybatis.generator.utils.StringUtils;
import org.mybatis.generator.api.*;
import org.mybatis.generator.api.dom.java.*;

import java.util.*;

/**
 * 业务层service,serviceImpl代码生成
 *
 * @author haoqizhe.li
 * @date 2018/4/16 16:43
 */
public class ServicePlugin extends PluginAdapter {
    private Properties systemPro;
    private FullyQualifiedJavaType serviceType;
    private FullyQualifiedJavaType pojoType;
    private FullyQualifiedJavaType daoType;
    private FullyQualifiedJavaType service;
    private FullyQualifiedJavaType returnType;
    /**
     * 类文件编码格式
     **/
    private String javaFileEncoding;
    /**
     * model类名
     **/
    private String tableName;
    /**
     * 表注释
     **/
    private Object tableComment;
    /**
     * service 包名
     **/
    private String servicePackage;
    /**
     * mapper 包名
     **/
    private String mapperPackage;
    /**
     * service文件夹名
     **/
    private String targetProject;
    /**
     * service 继承的父接口
     **/
    private String rootInterface;
    /**
     * 生成代码作者
     **/
    private String author;

    @Override
    public boolean validate(List<String> list) {
        return true;
    }

    /**
     * 获取属性配置
     *
     * @param properties 配置属性
     * @author haoqizhe.li
     * @date 2018/4/16 17:25
     **/
    @Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        systemPro = System.getProperties();
        servicePackage = properties.getProperty("servicePackage");
        mapperPackage = properties.getProperty("mapperPackage");
        targetProject = properties.getProperty("targetProject");
        rootInterface = properties.getProperty("rootInterface");
        javaFileEncoding = properties.getProperty("javaFileEncoding", "UTF-8");
        author = properties.getProperty("author", systemPro.getProperty("user.name"));

        boolean isCheckInterface = rootInterface == null || "".equals(rootInterface);
        if (isCheckInterface) {
            throw new RuntimeException("addInterface参数为真，需要继承父类接口，而父类接口rootInterface为空");
        }
        if (servicePackage == null || "".equals(servicePackage)) {
            throw new RuntimeException("ServicePlugin插件缺少必须的servicePackage参数值");
        }
        if (mapperPackage == null || "".equals(mapperPackage)) {
            throw new RuntimeException("ServicePlugin插件缺少必须的mapperPackage参数值");
        }
        if (targetProject == null || "".equals(targetProject)) {
            throw new RuntimeException("ServicePlugin插件缺少必须的targetProject参数值");
        }
    }

    /**
     * 控制生成service 和 serviceImpl
     *
     * @author haoqizhe.li
     * @date 2018/4/16 20:39
     **/
    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();

        tableComment = introspectedTable.getRemarks() == null || "".equals(introspectedTable.getRemarks()) ?
                introspectedTable.getFullyQualifiedTable() : introspectedTable.getRemarks();

        /**
         * 获取实体类名
         */
        String table = introspectedTable.getBaseRecordType();
        String[] names = table.split("\\.");
        tableName = names[names.length - 1];
        /**
         * mapper接口
         */
        daoType = new FullyQualifiedJavaType(mapperPackage + "." + tableName + "Mapper");
        /**
         * service 接口
         */
        serviceType = new FullyQualifiedJavaType(servicePackage + "." + tableName + "Service");
        /**
         * 实体类
         */
        pojoType = new FullyQualifiedJavaType(table);

        TopLevelClass topLevelClass = new TopLevelClass(serviceType);

        //导入必须的类
        addImport(topLevelClass);
        //添加注释
        topLevelClass.addJavaDocLine(StringUtils.getComment(tableComment + "接口", author));

        //实现类
        files.add(addServiceImpl(topLevelClass));

        return files;
    }

    /**
     * @param topLevelClass service实现类
     * @return service实现类文件
     * @author haoqizhe.li
     * @date 2018/4/16 20:40
     **/
    protected GeneratedJavaFile addServiceImpl(TopLevelClass topLevelClass) {
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);

        return new GeneratedJavaFile(topLevelClass, targetProject, javaFileEncoding, context.getJavaFormatter());
    }

    /**
     * 接口，实现类import 引用包
     * 接口继承父接口，实现类继承抽象类、实现接口 并添加相关注解
     *
     * @author haoqizhe.li
     * @date 2018/4/16 20:37
     **/
    private void addImport(TopLevelClass topLevelClass) {
        /**
         * service 继承父类接口
         */
        String genericityRootClass = String.format("<%s,%s>", daoType.getShortName(), tableName);
        String[] names = rootInterface.split("\\.");
        topLevelClass.setSuperClass(new FullyQualifiedJavaType(names[names.length - 1] + genericityRootClass));
        topLevelClass.addImportedType(rootInterface);

        topLevelClass.addAnnotation(AnnotationEnum.SERVICE.annotation);
        topLevelClass.addImportedType(AnnotationEnum.SERVICE.importedType);
        topLevelClass.addAnnotation(AnnotationEnum.SLF4J.annotation);
        topLevelClass.addImportedType(AnnotationEnum.SLF4J.importedType);
        topLevelClass.addImportedType(pojoType);
        topLevelClass.addImportedType(daoType);

    }

    @Override
    public boolean clientInsertMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        returnType = method.getReturnType().get();
        return true;
    }
}
